package com.wolfeyes.framework.springsecurity.handle;

import com.wolfeyes.common.constant.HttpStatusConstants;
import com.wolfeyes.common.response.ResponseResult;
import com.wolfeyes.common.utils.network.http.ServletUtils;
import com.wolfeyes.common.utils.character.StringUtils;

import lombok.extern.slf4j.Slf4j;

import com.alibaba.fastjson.JSON;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @description SpringSecurity安全认证权限框架
 * @description 实现AuthenticationEntryPoint接口,当匿名请求需要登录的接口时,拦截处理
 * @description 匿名未登录的时候访问,需要登录的资源的调用类
 * @description 匿名用户（未登录）访问无权限资源（需要登录）的调用类
 * @description 匿名未登录去直接访问一个需要认证之后才可以访问的请求
 * @description 匿名请求需要登录认证的接口-unauthorized Handler-EntryPointUnauthorizedHandler 
 * @see Talk is cheap, Show me the code. -- Linus Torvalds
 * @title 自定义的身份认证（失败）入口点（切入点）
 * @author yanyljava
 * @create 2022-01-14 21:25
 */
@Slf4j
@Component
public class CustomizeAuthenticationEntryPoint implements AuthenticationEntryPoint {

	@Override
	public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException authenticationException) throws IOException, ServletException {
		
		log.debug("自定义的匿名用户访问受保护权限资源（未认证需要登录）异常处理器被调用 Start！");
		// 访问受限，未授权（无权限访问，尚未登录，请先登录）
		int code = HttpStatusConstants.UNAUTHORIZED;
		
		// 认证未通过，不允许访问
		// 用户未通过认证访问受保护的资源时，将会调用其中的commence()方法进行处理，
		// 比如客户端携带的token被篡改，因此我们需要自定义一个AuthenticationEntryPoint返回特定的提示信息
		String msg = StringUtils.format("请求访问：{}，认证失败，无法访问系统资源", httpServletRequest.getRequestURI());
		
		// 设置response状态码，返回错误信息等
		ServletUtils.renderString(httpServletResponse, JSON.toJSONString(ResponseResult.error(code, msg)));
		log.debug("自定义的匿名用户访问受保护权限资源（未认证需要登录）异常处理器被调用 End！");
	}

}


